package io.github.loser.properties;

import com.mongodb.ConnectionString;
import org.bson.UuidRepresentation;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;


@ConfigurationProperties("spring.data.mongodb")
public class MogoProperties {

    public static final int DEFAULT_PORT = 27017;
    public static final String DEFAULT_URI = "mongodb://localhost/test";
    private String host;
    private Integer port = null;
    private String uri;
    private String database;
    private String authenticationDatabase;
    private final MongoProperties.Gridfs gridfs = new MongoProperties.Gridfs();
    private String username;
    private char[] password;
    private String replicaSetName;
    private Class<?> fieldNamingStrategy;
    private UuidRepresentation uuidRepresentation;
    private Boolean autoIndexCreation;

    /**
     * 是否开启自定义线程池配置
     */
    private Boolean usePoolSetting = false;

    /**
     * 连接池的最大连接数。默认值为 100。
     */
    private int maxSize = 100;

    /**
     * 连接池的最小连接数。默认值为 0。
     */
    private int minSize = 0;

    /**
     * 获取连接的最大等待时间（毫秒）。默认值为 120,000 毫秒（2 分钟）。
     */
    private long maxWaitTimeMs = 120000L;

    /**
     * 连接的最大生命周期（毫秒），超过该时间的连接将被关闭。默认值为 0（无限制）。
     */
    private long maxConnectionLifeTimeMs = 0L;

    /**
     * 连接的最大空闲时间（毫秒），超过该时间的空闲连接将被关闭。默认值为 0（无限制）。
     */
    private long maxConnectionIdleTimeMs = 0L;

    /**
     * 连接池维护线程的初始延迟时间（毫秒）。默认值为 0 毫秒。
     */
    private long maintenanceInitialDelayMs = 0L;

    /**
     * 连接池维护线程的频率（毫秒）。默认值为 60,000 毫秒（1 分钟）。
     */
    private long maintenanceFrequencyMs = 60000L;


    public int getMaxSize() {
        return maxSize;
    }

    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }

    public int getMinSize() {
        return minSize;
    }

    public void setMinSize(int minSize) {
        this.minSize = minSize;
    }

    public long getMaxWaitTimeMs() {
        return maxWaitTimeMs;
    }

    public void setMaxWaitTimeMs(long maxWaitTimeMs) {
        this.maxWaitTimeMs = maxWaitTimeMs;
    }

    public long getMaxConnectionLifeTimeMs() {
        return maxConnectionLifeTimeMs;
    }

    public void setMaxConnectionLifeTimeMs(long maxConnectionLifeTimeMs) {
        this.maxConnectionLifeTimeMs = maxConnectionLifeTimeMs;
    }

    public long getMaxConnectionIdleTimeMs() {
        return maxConnectionIdleTimeMs;
    }

    public void setMaxConnectionIdleTimeMs(long maxConnectionIdleTimeMs) {
        this.maxConnectionIdleTimeMs = maxConnectionIdleTimeMs;
    }

    public long getMaintenanceInitialDelayMs() {
        return maintenanceInitialDelayMs;
    }

    public void setMaintenanceInitialDelayMs(long maintenanceInitialDelayMs) {
        this.maintenanceInitialDelayMs = maintenanceInitialDelayMs;
    }

    public long getMaintenanceFrequencyMs() {
        return maintenanceFrequencyMs;
    }

    public void setMaintenanceFrequencyMs(long maintenanceFrequencyMs) {
        this.maintenanceFrequencyMs = maintenanceFrequencyMs;
    }

    public MogoProperties() {
        this.uuidRepresentation = UuidRepresentation.JAVA_LEGACY;
    }

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getDatabase() {
        return this.database;
    }

    public void setDatabase(String database) {
        this.database = database;
    }

    public String getAuthenticationDatabase() {
        return this.authenticationDatabase;
    }

    public void setAuthenticationDatabase(String authenticationDatabase) {
        this.authenticationDatabase = authenticationDatabase;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public char[] getPassword() {
        return this.password;
    }

    public void setPassword(char[] password) {
        this.password = password;
    }

    public String getReplicaSetName() {
        return this.replicaSetName;
    }

    public void setReplicaSetName(String replicaSetName) {
        this.replicaSetName = replicaSetName;
    }

    public Class<?> getFieldNamingStrategy() {
        return this.fieldNamingStrategy;
    }

    public void setFieldNamingStrategy(Class<?> fieldNamingStrategy) {
        this.fieldNamingStrategy = fieldNamingStrategy;
    }

    public UuidRepresentation getUuidRepresentation() {
        return this.uuidRepresentation;
    }

    public void setUuidRepresentation(UuidRepresentation uuidRepresentation) {
        this.uuidRepresentation = uuidRepresentation;
    }

    public String getUri() {
        return this.uri;
    }

    public String determineUri() {
        return this.uri != null ? this.uri : "mongodb://localhost/test";
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public Integer getPort() {
        return this.port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public MongoProperties.Gridfs getGridfs() {
        return this.gridfs;
    }

    public String getMongoClientDatabase() {
        return this.database != null ? this.database : (new ConnectionString(this.determineUri())).getDatabase();
    }

    public Boolean isAutoIndexCreation() {
        return this.autoIndexCreation;
    }

    public void setAutoIndexCreation(Boolean autoIndexCreation) {
        this.autoIndexCreation = autoIndexCreation;
    }

    public Boolean getAutoIndexCreation() {
        return autoIndexCreation;
    }

    public Boolean getUsePoolSetting() {
        return usePoolSetting;
    }

    public void setUsePoolSetting(Boolean usePoolSetting) {
        this.usePoolSetting = usePoolSetting;
    }

    @Override
    public String toString() {
        return "MogoProperties{" +
                "host='" + host + '\'' +
                ", port=" + port +
                ", uri='" + "***" + '\'' +
                ", database='" + database + '\'' +
                ", authenticationDatabase='" + authenticationDatabase + '\'' +
                ", gridfs=" + gridfs +
                ", username='" + username + '\'' +
                ", password=" + "***" +
                ", replicaSetName='" + replicaSetName + '\'' +
                ", fieldNamingStrategy=" + fieldNamingStrategy +
                ", uuidRepresentation=" + uuidRepresentation +
                ", autoIndexCreation=" + autoIndexCreation +
                ", usePoolSetting=" + usePoolSetting +
                ", maxSize=" + maxSize +
                ", minSize=" + minSize +
                ", maxWaitTimeMs=" + maxWaitTimeMs +
                ", maxConnectionLifeTimeMs=" + maxConnectionLifeTimeMs +
                ", maxConnectionIdleTimeMs=" + maxConnectionIdleTimeMs +
                ", maintenanceInitialDelayMs=" + maintenanceInitialDelayMs +
                ", maintenanceFrequencyMs=" + maintenanceFrequencyMs +
                '}';
    }
}
